﻿#nullable enable
using System.Linq;
using System.Text;

namespace ch02.binary.type
{
    public struct FuncType
    {
        public byte Tag;
        public ValType[] ParamTypes;
        public ValType[] ResultTypes;

        public override bool Equals(object obj)
        {
            if (obj is not FuncType ft2) return false;
            //return reflect.DeepEqual(ft, ft2)
            if (ParamTypes.Length != ft2.ParamTypes.Length)
            {
                return false;
            }

            if (ResultTypes.Length != ft2.ResultTypes.Length)
            {
                return false;
            }

            if (ParamTypes.Where((vt, i) => vt != ft2.ParamTypes[i]).Any())
            {
                return false;
            }

            return !ResultTypes.Where((vt, i) => vt != ft2.ResultTypes[i]).Any();

        }

        private string GetSignature()
        {
            var sb = new StringBuilder();
            sb.Append('(');
            for (var i = 0; i < ParamTypes.Length; i++)
            {
                var vt = ParamTypes[i];
                if (i > 0)
                {
                    sb.Append(',');
                }

                sb.Append(Types.ValTypeToStr(vt));
            }

            sb.Append(")->(");
            for (var i = 0; i < ResultTypes.Length; i++)
            {
                var vt = ResultTypes[i];
                if (i > 0)
                {
                    sb.Append(',');
                }

                sb.Append(Types.ValTypeToStr(vt));
            }

            sb.Append(')');
            return sb.ToString();
        }

        public override string ToString()
        {
            return GetSignature();
        }

        public static bool operator ==(FuncType left, FuncType right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(FuncType left, FuncType right)
        {
            return !(left == right);
        }
    }
}